package com.cdshangpai.utils.offlinecache.base;

import android.graphics.Bitmap;
import android.text.TextUtils;
import android.util.Log;

import com.cdshangpai.PhotoappApplication;
import com.cdshangpai.photoapp.LogConfig;
import com.cdshangpai.utils.db.beans.Case;
import com.cdshangpai.utils.db.beans.Hotal;
import com.cdshangpai.utils.db.beans.Video;
import com.cdshangpai.utils.log.LogUtil;
import com.cdshangpai.utils.offlinecache.DbVersion;
import com.cdshangpai.utils.offlinecache.base.slot.AdvantagephotosPicker;
import com.cdshangpai.utils.offlinecache.base.slot.CasephotosPicker;
import com.cdshangpai.utils.offlinecache.base.slot.ChargesphotosPicker;
import com.cdshangpai.utils.offlinecache.base.slot.DocumentphotosPicker;
import com.cdshangpai.utils.offlinecache.base.slot.HomePhotoPicker;
import com.cdshangpai.utils.offlinecache.base.slot.IdPicker;
import com.cdshangpai.utils.offlinecache.base.slot.IdeaPhotosPicker;
import com.cdshangpai.utils.offlinecache.base.slot.LetterphotosPicker;
import com.cdshangpai.utils.offlinecache.base.slot.PhotosPicker;
import com.cdshangpai.utils.offlinecache.base.slot.ProcessphotosPicker;
import com.cdshangpai.utils.offlinecache.base.slot.PromotionphotosPicker;
import com.cdshangpai.utils.offlinecache.base.slot.ServicePhotosPicker;
import com.cdshangpai.utils.offlinecache.base.slot.TitleImagePicker;
import com.cdshangpai.utils.offlinecache.base.slot.VersionPicker;
import com.cdshangpai.utils.offlinecache.base.slot.VideoPicker;
import com.cdshangpai.utils.storage.FileInput;
import com.cdshangpai.utils.storage.FileOutput;
import com.cdshangpai.utils.storage.ImageManager;
import com.cdshangpai.utils.storage.VideoManage;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;

/**
 * 通用缓存处理器
 */
public class BaseCacheProcessor<DBBEAN> {
    //本地数据库数据
    private List<DBBEAN> localDatas;
    //服务器数据
    private List<DBBEAN> serverDatas;
    //服务器版本数据
    private List<DbVersion> serverVersions;
    //服务器数据id集合
    private HashSet<Integer> serverIds;
    //服务器版本数据hash集
    private HashMap<Integer,DbVersion> serverVersionMap;
    //本地数据hash集
    private HashMap<Integer,DBBEAN> localMap;
    //服务器数据hash集
    private HashMap<Integer,DBBEAN> serverMap;
    //数据库处理接口
    private DbQuery dbQuery;
    //网络下载接口
    private DataDownloader<DBBEAN> dataDownloader;
    private ImageManager imageManager;
    private VideoManage videoManage;

    private boolean processTitleImage;
    private boolean processPhotos;
    private boolean processVideo;
    private boolean processHomePhotos;

    private boolean processIdeaPhotos;
    private boolean processServicePhotos;
    private boolean processAdvantagepPotos;
    private boolean processCasePhotos;
    private boolean processChargesPhotos;
    private boolean processPromotionPhotos;
    private boolean processLetterPhotos;
    private boolean processProcessPhotos;
    private boolean processDocumentPhotos;

    private boolean haveUpdate=false;

    public boolean getHaveUpdate()
    {
        return haveUpdate;
    }

    /**
     * 构造对象
     */
    public BaseCacheProcessor()
    {
        imageManager=new ImageManager();
        videoManage=new VideoManage();
    }

    /**
     * 设置服务器版本数据
     * @param serverVersions
     * @return
     */
    public BaseCacheProcessor setServerVersion(List<DbVersion> serverVersions)
    {
        this.serverVersions=serverVersions;
        return this;
    }

    /**
     * 设置本地数据
     * @param localDatas
     * @return
     */
    public BaseCacheProcessor setLocalDatas(List<DBBEAN> localDatas)
    {
        this.localDatas=localDatas;
        localMap=new HashMap<>();
        for(DBBEAN dbbean:this.localDatas)
        {
            IdPicker idPicker=(IdPicker)dbbean;
            localMap.put(idPicker.getId(),dbbean);
        }
        return this;
    }

    /**
     * 设置数据库查询处理器
     * @param dbQuery
     * @return
     */
    public BaseCacheProcessor setDbQuery(DbQuery dbQuery)
    {
        this.dbQuery=dbQuery;
        return this;
    }

    /**
     * 设置服务器数据下载器
     * @param dataDownloader
     * @return
     */
    public BaseCacheProcessor setDataDownloader(DataDownloader dataDownloader)
    {
        this.dataDownloader=dataDownloader;
        return this;
    }

    public BaseCacheProcessor forCase()
    {
        this.processTitleImage=true;
        this.processPhotos=true;
        return this;
    }

    public BaseCacheProcessor forVideo()
    {
        this.processTitleImage=true;
        this.processVideo=true;
        return this;
    }

    public BaseCacheProcessor forHotal()
    {
        return this.forCase();
    }

    public BaseCacheProcessor forAccount()
    {
        return this;
    }

    public BaseCacheProcessor forAboutus()
    {
        this.processPhotos=true;
        this.processHomePhotos=true;
        this.processIdeaPhotos=true;
        this.processServicePhotos=true;
        this.processAdvantagepPotos=true;
        this.processCasePhotos=true;
        this.processChargesPhotos=true;
        this.processPromotionPhotos=true;
        this.processLetterPhotos=true;
        this.processProcessPhotos=true;
        this.processDocumentPhotos=true;
        return this;
    }

    /**
     * 开始执行处理
     * @return
     */
    public boolean begin()
    {
        formatServerCache();
        deleteLocalDbNotInServer();
        filterUnChangeData();
        if(serverIds.size()==0)
        {
            //本地数据检测后，没有变化，退出处理
            return true;
        }
        haveUpdate=true;
        if(!downloadServerData())
        {
            return false;
        }
        return update();
    }

    /**
     * 使用服务器版本数据创建对比数据
     */
    private void formatServerCache()
    {
        serverIds=new HashSet<>();
        serverVersionMap=new HashMap<>();
        for(DbVersion version:serverVersions)
        {
            serverIds.add(version.id);
            serverVersionMap.put(version.id,version);
        }
    }


    /**
     * 删除服务器没有的数据
     */
    private void deleteLocalDbNotInServer()
    {
        for(int i=localDatas.size()-1;i>=0;i--)
        {
            IdPicker idPicker=(IdPicker)localDatas.get(i);
            if(!serverIds.contains(idPicker.getId()))
            {
                localSourceDelete(localDatas.get(i));
                dbQuery.delete(idPicker.getId());
                localDatas.remove(idPicker.getId());

                haveUpdate=true;
            }
        }
    }

    /**
     * 剔除没有产生变化的数据
     */
    private void filterUnChangeData()
    {
        for(int i=serverVersions.size()-1;i>=0;i--)
        {
            IdPicker idPicker=(IdPicker)serverVersions.get(i);
            VersionPicker serverVersionPicker=(VersionPicker)serverVersions.get(i);
            if(localMap.containsKey(idPicker.getId()))
            {
                VersionPicker localVersionPicker=(VersionPicker)localMap.get(idPicker.getId());
                if(serverVersionPicker.getVersion().equals(localVersionPicker.getVersion()))
                {
                    //数据没有发生变化，进行剔除
                    serverVersions.remove(i);
                    serverIds.remove(idPicker.getId());
                    serverVersionMap.remove(idPicker.getId());

                    DBBEAN localBean=localMap.get(idPicker.getId());
                    localDatas.remove(localBean);
                    localMap.remove(idPicker.getId());
                }
            }
        }
    }

    /**
     * 下载服务器详细数据
     * @return
     */
    private boolean  downloadServerData()
    {
        List<Integer> ids=new ArrayList<>();
        for(Integer id:serverIds)
        {
            ids.add(id);
        }
        serverDatas=dataDownloader.download(ids);
        if(serverDatas==null)
        {
            return false;
        }
        serverMap=new HashMap<>();
        for(DBBEAN bean:serverDatas)
        {
            IdPicker idPicker=(IdPicker)bean;
            serverMap.put(idPicker.getId(),bean);
        }
        return true;
    }

    /**
     * 更新数据
     * @return
     */
    private boolean update()
    {
        Boolean result=true;
        for(DBBEAN serverBean:serverDatas)
        {
            String title=getTitle(serverBean);
            if(title!=null)
            {
                LogUtil.save("开始同步："+title);
                Log.i(LogConfig.logTag,"开始同步："+title);
            }
            IdPicker serverIdPicker=(IdPicker)serverBean;
            boolean isadd=!localMap.containsKey(serverIdPicker.getId());
            if(!isadd)
            {
                //修改数据
                //删除本地原有图片或视频
                /*DBBEAN localBean=localMap.get(serverIdPicker.getId());
                localSourceDelete(localBean);*/
            }
            boolean success=sourceDownload(serverBean);
//            result=result&&success;
            if(!success)
            {
                result=false;
//                return false;
            }
            if(success) {
                if (isadd) {
                    dbQuery.insert(serverBean);
                } else {
                    DBBEAN localBean=localMap.get(serverIdPicker.getId());
                    localSourceDelete(localBean);

                    dbQuery.update(serverBean);
                }
            }
            if(title!=null)
            {
                LogUtil.save("完成同步，结果："+(success?"成功":"失败"));
                Log.i(LogConfig.logTag,"完成同步，结果："+(success?"成功":"失败"));
            }
        }
        return result;
    }

    /**
     * 获取名称
     * @param serverBean
     * @return
     */
    private String getTitle(DBBEAN serverBean)
    {
        if(serverBean instanceof Case)
        {
            return ((Case)serverBean).getTitle();
        }else if(serverBean instanceof Hotal)
        {
            return ((Hotal)serverBean).getName();
        }else if(serverBean instanceof Video)
        {
            return ((Video)serverBean).getTitle();
        }else
        {
            return null;
        }
    }

    /**
     * 删除本地资源
     * @param bean
     * @return
     */
    private boolean localSourceDelete(DBBEAN bean)
    {
        if(processTitleImage)
        {
            TitleImagePicker titleImagePicker=(TitleImagePicker)bean;
            deleteImages(titleImagePicker.getTitleimg());
        }
        if(processPhotos)
        {
            PhotosPicker photosPicker=(PhotosPicker)bean;
            deleteImages(photosPicker.getPhotos());
        }
        if(processHomePhotos)
        {
            HomePhotoPicker homePhotoPicker=(HomePhotoPicker)bean;
            deleteImages(homePhotoPicker.getHomePhotos());
        }
        if(processVideo)
        {
            VideoPicker videoPicker=(VideoPicker)bean;
            deleteVideos(videoPicker.getUrl());
        }
        if(processIdeaPhotos)
        {
            IdeaPhotosPicker ideaPhotosPicker=(IdeaPhotosPicker)bean;
            deleteImages(ideaPhotosPicker.getIdeaphotos());
        }
        if(processServicePhotos)
        {
            ServicePhotosPicker servicePhotosPicker=(ServicePhotosPicker)bean;
            deleteImages(servicePhotosPicker.getServicephotos());
        }
        if(processAdvantagepPotos)
        {
            AdvantagephotosPicker advantagephotosPicker=(AdvantagephotosPicker)bean;
            deleteImages(advantagephotosPicker.getAdvantagephotos());
        }
        if(processCasePhotos)
        {
            CasephotosPicker casephotosPicker=(CasephotosPicker)bean;
            deleteImages(casephotosPicker.getCasephotos());
        }
        if(processChargesPhotos)
        {
            ChargesphotosPicker chargesphotosPicker=(ChargesphotosPicker)bean;
            deleteImages(chargesphotosPicker.getChargesphotos());
        }
        if(processPromotionPhotos)
        {
            PromotionphotosPicker promotionphotosPicker=(PromotionphotosPicker)bean;
            deleteImages(promotionphotosPicker.getPromotionphotos());
        }
        if(processLetterPhotos)
        {
            LetterphotosPicker letterphotosPicker=(LetterphotosPicker)bean;
            deleteImages(letterphotosPicker.getLetterphotos());
        }
        if(processProcessPhotos)
        {
            ProcessphotosPicker processphotosPicker=(ProcessphotosPicker)bean;
            deleteImages(processphotosPicker.getProcessphotos());
        }
        if(processDocumentPhotos)
        {
            DocumentphotosPicker documentphotosPicker=(DocumentphotosPicker)bean;
            deleteImages(documentphotosPicker.getDocumentphotos());
        }
        return true;
    }

    /**
     * 批量输出图片
     * @param fileNames
     */
    private void deleteImages(String fileNames)
    {
        if(TextUtils.isEmpty(fileNames))
        {
            return;
        }
        String[] files=fileNames.split(",");
        for(String fileName:files)
        {
            deleteImage(fileName);
        }
    }

    /**
     * 删除单独图片
     * @param fileName
     */
    private void deleteImage(String fileName)
    {
        if(TextUtils.isEmpty(fileName))
        {
            return;
        }
        imageManager.deleteImages(fileName);
    }

    /**
     * 批量删除视频
     * @param fileNames
     */
    private void deleteVideos(String fileNames)
    {
        Log.i(LogConfig.logTag,"准备删除视频:"+fileNames);
        if(TextUtils.isEmpty(fileNames))
        {
            return;
        }
        String[] files=fileNames.split(",");
        for(String fileName:files)
        {
            deleteVideo(fileName);
        }
    }

    /**
     * 删除单独视频
     * @param fileName
     */
    private void deleteVideo(String fileName)
    {
        if(TextUtils.isEmpty(fileName))
        {
            return;
        }
        videoManage.delete(fileName);
    }

    /**
     * 标题图限制宽度尺寸
     * @param filename
     * @param maxWidth
     */
    private void convert2MaxSize(String filename,Integer maxWidth)
    {
        ImageManager imageManager=new ImageManager();
        Bitmap bitmap=imageManager.loadImageToBitmap(filename);
        if(bitmap==null)
        {
            return;
        }
        if(bitmap.getWidth()>maxWidth)
        {
            Bitmap desc=imageManager.scale(bitmap,maxWidth);
            FileOutput fileOutput=new FileOutput(PhotoappApplication.context,ImageManager.imageBaseFolder,filename,true);
            fileOutput.write(ImageManager.encryptionbuf);
            desc.compress(Bitmap.CompressFormat.JPEG,100,fileOutput.getOutputStream());
            fileOutput.flush();
            fileOutput.close();
        }
    }

    /**
     * 图片视频资源下载
     * @param bean
     * @return
     */
    private boolean sourceDownload(DBBEAN bean)
    {
        if(processTitleImage)
        {
            TitleImagePicker titleImagePicker=(TitleImagePicker)bean;
            String titleimgUrl=titleImagePicker.getTitleimgUrl();
            if(!TextUtils.isEmpty(titleimgUrl)) {
                String titleImage = downloadImage(titleimgUrl);
                if (TextUtils.isEmpty(titleImage)) {
                    return false;
                }
//                convert2MaxSize(titleImage,400);
                titleImagePicker.setTitleimg(titleImage);
            }
        }
        if(processPhotos)
        {
            PhotosPicker photosPicker=(PhotosPicker)bean;
            String photosUrl=photosPicker.getPhotosUrl();
            if(!TextUtils.isEmpty(photosUrl)) {
                String photos = downloadImages(photosUrl);
                if (TextUtils.isEmpty(photos)) {
                    localSourceDelete(bean);
                    return false;
                }
                photosPicker.setPhotos(photos);
            }
        }
        if(processHomePhotos)
        {
            HomePhotoPicker homePhotoPicker=(HomePhotoPicker)bean;
            String  homePhotosUrl=homePhotoPicker.getHomePhotosUrl();
            if(!TextUtils.isEmpty(homePhotosUrl)) {
                String homePhotos = downloadImages(homePhotosUrl);
                if (TextUtils.isEmpty(homePhotos)) {
                    localSourceDelete(bean);
                    return false;
                }
                homePhotoPicker.setHomePhotos(homePhotos);
            }
        }
        if(processVideo)
        {
            VideoPicker videoPicker=(VideoPicker)bean;
            String videoUrl=videoPicker.getVideoUrl();
            if(!TextUtils.isEmpty(videoUrl)) {
                String video = downloadVideo(videoUrl);
                if (TextUtils.isEmpty(video)) {
                    localSourceDelete(bean);
                    return false;
                }
                videoPicker.setUrl(video);
            }
        }
        if(processIdeaPhotos)
        {
            IdeaPhotosPicker ideaPhotosPicker=(IdeaPhotosPicker)bean;
            String ideaPhotoUrl=ideaPhotosPicker.getIdeaphotoUrls();
            if(!TextUtils.isEmpty(ideaPhotoUrl))
            {
                String ideaPhotos=downloadImages(ideaPhotoUrl);
                if(TextUtils.isEmpty(ideaPhotos))
                {
                    localSourceDelete(bean);
                    return false;
                }
                ideaPhotosPicker.setIdeaphotos(ideaPhotos);
            }
        }
        if(processServicePhotos)
        {
            ServicePhotosPicker servicePhotosPicker=(ServicePhotosPicker)bean;
            String servicePhotoUrls=servicePhotosPicker.getServicephotoUrls();
            if(!TextUtils.isEmpty(servicePhotoUrls))
            {
                String servicePhotos=downloadImages(servicePhotoUrls);
                if(TextUtils.isEmpty(servicePhotos))
                {
                    localSourceDelete(bean);
                    return false;
                }
                servicePhotosPicker.setServicephotos(servicePhotos);
            }
        }
        if(processAdvantagepPotos)
        {
            AdvantagephotosPicker advantagephotosPicker=(AdvantagephotosPicker)bean;
            String advantagephotoUrls=advantagephotosPicker.getAdvantagephotoUrls();
            if(!TextUtils.isEmpty(advantagephotoUrls))
            {
                String advantagePhotos=downloadImages(advantagephotoUrls);
                if(TextUtils.isEmpty(advantagePhotos))
                {
                    localSourceDelete(bean);
                    return false;
                }
                advantagephotosPicker.setAdvantagephotos(advantagePhotos);
            }
        }
        if(processCasePhotos)
        {
            CasephotosPicker casephotosPicker=(CasephotosPicker)bean;
            String casephotoUrls=casephotosPicker.getCasephotoUrls();
            if(!TextUtils.isEmpty(casephotoUrls))
            {
                String casephotos=downloadImages(casephotoUrls);
                if(TextUtils.isEmpty(casephotos))
                {
                    localSourceDelete(bean);
                    return false;
                }
                casephotosPicker.setCasephotos(casephotos);
            }
        }
        if(processChargesPhotos)
        {
            ChargesphotosPicker chargesphotosPicker=(ChargesphotosPicker)bean;
            String chargesphotoUrls=chargesphotosPicker.getChargesphotoUrls();
            if(!TextUtils.isEmpty(chargesphotoUrls))
            {
                String chargesphotos=downloadImages(chargesphotoUrls);
                if(TextUtils.isEmpty(chargesphotos))
                {
                    localSourceDelete(bean);
                    return false;
                }
                chargesphotosPicker.setChargesphotos(chargesphotos);
            }
        }
        if(processPromotionPhotos)
        {
            PromotionphotosPicker promotionphotosPicker=(PromotionphotosPicker)bean;
            String promotionphotoUrls=promotionphotosPicker.getPromotionphotoUrls();
            if(!TextUtils.isEmpty(promotionphotoUrls))
            {
                String promotionphotos=downloadImages(promotionphotoUrls);
                if(TextUtils.isEmpty(promotionphotos))
                {
                    localSourceDelete(bean);
                    return false;
                }
                promotionphotosPicker.setPromotionphotos(promotionphotos);
            }
        }
        if(processLetterPhotos)
        {
            LetterphotosPicker letterphotosPicker=(LetterphotosPicker)bean;
            String letterphotoUrls=letterphotosPicker.getLetterphotoUrls();
            if(!TextUtils.isEmpty(letterphotoUrls))
            {
                String letterphotos=downloadImages(letterphotoUrls);
                if(TextUtils.isEmpty(letterphotos))
                {
                    localSourceDelete(bean);
                    return false;
                }
                letterphotosPicker.setLetterphotos(letterphotos);
            }
        }
        if(processProcessPhotos)
        {
            ProcessphotosPicker processphotosPicker=(ProcessphotosPicker)bean;
            String processphotoUrls=processphotosPicker.getProcessphotoUrls();
            if(!TextUtils.isEmpty(processphotoUrls))
            {
                String processphotos=downloadImages(processphotoUrls);
                if(TextUtils.isEmpty(processphotos))
                {
                    localSourceDelete(bean);
                    return false;
                }
                processphotosPicker.setProcessphotos(processphotos);
            }
        }
        if(processDocumentPhotos)
        {
            DocumentphotosPicker documentphotosPicker=(DocumentphotosPicker)bean;
            String documentphotoUrls=documentphotosPicker.getDocumentphotoUrls();
            if(!TextUtils.isEmpty(documentphotoUrls))
            {
                String documentphotos=downloadImages(documentphotoUrls);
                if(TextUtils.isEmpty(documentphotos))
                {
                    localSourceDelete(bean);
                    return false;
                }
                documentphotosPicker.setDocumentphotos(documentphotos);
            }
        }
        return true;
    }

    /**
     * 批量下载图片
     * @param urls
     * @return
     */
    private String downloadImages(String urls)
    {
        if(TextUtils.isEmpty(urls))
        {
            Log.i(LogConfig.logTag,"图片资源无效");
            return null;
        }
        List<String> images=new ArrayList<>();
        String[] urlArray=urls.split(",");
        for(String url:urlArray)
        {
            if(TextUtils.isEmpty(url))
            {
                Log.i(LogConfig.logTag,"图片url为空:");
                continue;
            }
            String fileName=downloadImage(url);
            if(fileName==null)
            {
                //有下载失败，删除前面下载的内容
                deleteImages(TextUtils.join(",",images.toArray()));
                Log.i(LogConfig.logTag,"图片下载失败，url:"+(TextUtils.isEmpty(url)?"":url));
                return null;
            }
            images.add(fileName);
        }
        return TextUtils.join(",",images.toArray());
    }

    /**
     * 下载单独图片
     * @return
     */
    private String downloadImage(String url)
    {
        return imageManager.download(url);
    }

    /**
     * 批量下载视频
     * @param urls
     * @return
     */
    private String downloadVideos(String urls)
    {
        if(TextUtils.isEmpty(urls))
        {
            return null;
        }
        List<String> videos=new ArrayList<>();
        String[] urlArray=urls.split(",");
        for(String url:urlArray)
        {
            String fileName=downloadImage(url);
            if(fileName==null)
            {
                //有下载失败，删除前面下载的内容
                deleteVideos(TextUtils.join(",",videos.toArray()));
                return null;
            }
            videos.add(fileName);
        }
        return TextUtils.join(",",videos.toArray());
    }

    /**
     * 下载单独视频
     * @param url
     * @return
     */
    private String downloadVideo(String url)
    {
        return videoManage.download(url);
    }
}
